//Random Game Engine
//Copyright (C) 2013  Nikolay Dionisov

//This program is free software: you can redistribute it and/or modify
//it under the terms of the GNU General Public License as published by
//the Free Software Foundation, either version 3 of the License, or
//(at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program.  If not, see <http://www.gnu.org/licenses/>.



#ifndef __STATE_MANAGER__H_INCLUDED__
#define __STATE_MANAGER__H_INCLUDED__
#include <memory>
#include <map>
#include <vector>

#include "..\..\Utilities\ThreadSafePrimitives.h"
#include "..\..\SystemInterface.h"
#include "..\ManagerInterfaces.h"

namespace re
{
	namespace core
	{
	
		class StateListener : public IStateListener
		{
		public:
			StateListener() {}
			~StateListener() {}

			void SetMsgCallback(MessageType type, StateListenerCallbackPtr callback);
			void RemoveMsgCallback(MessageType type);
			void Update();
		protected:
			void HandleMessage(StateMessagePtr msg);
		private:
			ut::RealtimeQueue<StateMessagePtr> queue_;
			StateListenerCallbackMap callback_map;
		};
		typedef std::vector<StateListenerPtr> StateListenerList;
		typedef std::map<MessageType, StateListenerList> StateListenerMap;


		class StateManager : public IStateManager
		{
		public:
			StateManager() {}
			~StateManager() {}

			MessageType GenerateNewMsgType();
			void RegisterMsgType(MessageType type);
			void UnregisterMsgType(MessageType type);
			void RegisterListener(StateListenerPtr listener, MessageType type);
			void UnregisterListener(StateListenerPtr listener);

			void SendMsg(StateMessagePtr msg);

			StateListenerPtr CreateStateListener();
		private:
			StateListenerMap listenermap_;
			MessageType last_messagetype;
			mutable std::mutex mutex_;
		};
	}
}
#endif